Flutter アプリをプログラムでデバッグする
このドキュメントでは、コードで有効にできるデバッグ機能について説明します。 デバッグおよびプロファイリング ツールの完全なリストについては、デバッグページ。
ロギング
アプリケーションのログ記録には 2 つのオプションがあります。
1つ目は、使用することですstdout
とstderr
。
一般に、これは次を使用して行われますprint()
ステートメント、
または輸入することでdart:io
そしてメソッドを呼び出すstderr
とstdout
。例えば:
stderr.writeln('print me');
一度に大量に出力すると、Android が時々
いくつかのログ行を破棄します。これを回避するには、次を使用しますdebugPrint()
、
flutterズからfoundation
図書館。これはラッパーアラウンドですprint
出力が低下しないレベルまで出力を抑制します。
Androidのカーネル。
アプリケーションログのもう 1 つのオプションは、dart:developer
log()
関数。これにより、
ログ出力の粒度と情報がもう少し詳しくなります。
以下に例を示します。
import 'dart:developer' as developer;
void main() {
developer.log('log me', name: 'my.app.category');
developer.log('log me 1', name: 'my.other.category');
developer.log('log me 2', name: 'my.other.category');
}
アプリケーション データをログ呼び出しに渡すこともできます。
このための規則では、error:
名前付き
のパラメータlog()
呼び出し、オブジェクトを JSON エンコードする
送信したいものを選択し、エンコードされた文字列を
エラーパラメータ。
import 'dart:convert';
import 'dart:developer' as developer;
void main() {
var myCustomObject = MyCustomObject();
developer.log(
'log me',
name: 'my.app.category',
error: jsonEncode(myCustomObject),
);
}
DevTool のログ ビューでログ出力を表示する場合は、 JSON エンコードされたエラー パラメータはデータ オブジェクトとして解釈されます そして、そのログ エントリの詳細ビューにレンダリングされます。
ブレークポイントの設定
プログラムによるブレークポイントを挿入するには、debugger()
声明。これを使用するには、次のことを行う必要があります
をインポートするdart:developer
上部のパッケージ
関連するファイル。
のdebugger()
ステートメントはオプションを取りますwhen
次の場合にのみ中断するように指定できる引数
次の例のように、特定の条件が true です。
import 'dart:developer';
void someFunction(double offset) {
debugger(when: offset > 30);
// ...
}
デバッグ フラグ: アプリケーション層
Flutter フレームワークの各層は、その層をダンプする機能を提供します。
現在の状態またはイベントをコンソールに送信します (使用debugPrint
)。
ウィジェットツリー
ウィジェット ライブラリの状態をダンプするには、次の呼び出しを行います。debugDumpApp()
。
アプリケーションが実行されていないときは、多かれ少なかれこれをいつでも呼び出すことができます。
ビルドフェーズの実行中 (つまり、ビルドフェーズ内のどこにもありません)build()
メソッド)、アプリが少なくとも 1 回ビルドされており、デバッグ モードにある場合
(つまり、電話をかけた後はいつでもrunApp()
)。
たとえば、次のようなアプリケーションです。
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: AppHome(),
),
);
}
class AppHome extends StatelessWidget {
const AppHome({super.key});
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: TextButton(
onPressed: () {
debugDumpApp();
},
child: const Text('Dump App'),
),
),
);
}
}
前のアプリは次のような出力を行います (正確な詳細はフレームワークのバージョンによって異なります。 デバイスのサイズなど):
I/flutter ( 6559): WidgetsFlutterBinding - CHECKED MODE
I/flutter ( 6559): RenderObjectToWidgetAdapter<RenderBox>([GlobalObjectKey RenderView(497039273)]; renderObject: RenderView)
I/flutter ( 6559): └MaterialApp(state: _MaterialAppState(1009803148))
I/flutter ( 6559): └ScrollConfiguration()
I/flutter ( 6559): └AnimatedTheme(duration: 200ms; state: _AnimatedThemeState(543295893; ticker inactive; ThemeDataTween(ThemeData(Brightness.light Color(0xff2196f3) etc...) → null)))
I/flutter ( 6559): └Theme(ThemeData(Brightness.light Color(0xff2196f3) etc...))
I/flutter ( 6559): └WidgetsApp([GlobalObjectKey _MaterialAppState(1009803148)]; state: _WidgetsAppState(552902158))
I/flutter ( 6559): └CheckedModeBanner()
I/flutter ( 6559): └Banner()
I/flutter ( 6559): └CustomPaint(renderObject: RenderCustomPaint)
I/flutter ( 6559): └DefaultTextStyle(inherit: true; color: Color(0xd0ff0000); family: "monospace"; size: 48.0; weight: 900; decoration: double Color(0xffffff00) TextDecoration.underline)
I/flutter ( 6559): └MediaQuery(MediaQueryData(size: Size(411.4, 683.4), devicePixelRatio: 2.625, textScaleFactor: 1.0, padding: EdgeInsets(0.0, 24.0, 0.0, 0.0)))
I/flutter ( 6559): └LocaleQuery(null)
I/flutter ( 6559): └Title(color: Color(0xff2196f3))
I/flutter ( 6559): └Navigator([GlobalObjectKey<NavigatorState> _WidgetsAppState(552902158)]; state: NavigatorState(240327618; tracking 1 ticker))
I/flutter ( 6559): └Listener(listeners: down, up, cancel; behavior: defer-to-child; renderObject: RenderPointerListener)
I/flutter ( 6559): └AbsorbPointer(renderObject: RenderAbsorbPointer)
I/flutter ( 6559): └Focus([GlobalKey 489139594]; state: _FocusState(739584448))
I/flutter ( 6559): └Semantics(container: true; renderObject: RenderSemanticsAnnotations)
I/flutter ( 6559): └_FocusScope(this scope has focus; focused subscope: [GlobalObjectKey MaterialPageRoute<void>(875520219)])
I/flutter ( 6559): └Overlay([GlobalKey 199833992]; state: OverlayState(619367313; entries: [OverlayEntry@248818791(opaque: false; maintainState: false), OverlayEntry@837336156(opaque: false; maintainState: true)]))
I/flutter ( 6559): └_Theatre(renderObject: _RenderTheatre)
I/flutter ( 6559): └Stack(renderObject: RenderStack)
I/flutter ( 6559): ├_OverlayEntry([GlobalKey 612888877]; state: _OverlayEntryState(739137453))
I/flutter ( 6559): │└IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer)
I/flutter ( 6559): │ └ModalBarrier()
I/flutter ( 6559): │ └Semantics(container: true; renderObject: RenderSemanticsAnnotations)
I/flutter ( 6559): │ └GestureDetector()
I/flutter ( 6559): │ └RawGestureDetector(state: RawGestureDetectorState(39068508; gestures: tap; behavior: opaque))
I/flutter ( 6559): │ └_GestureSemantics(renderObject: RenderSemanticsGestureHandler)
I/flutter ( 6559): │ └Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener)
I/flutter ( 6559): │ └ConstrainedBox(BoxConstraints(biggest); renderObject: RenderConstrainedBox)
I/flutter ( 6559): └_OverlayEntry([GlobalKey 727622716]; state: _OverlayEntryState(279971240))
I/flutter ( 6559): └_ModalScope([GlobalKey 816151164]; state: _ModalScopeState(875510645))
I/flutter ( 6559): └Focus([GlobalObjectKey MaterialPageRoute<void>(875520219)]; state: _FocusState(331487674))
I/flutter ( 6559): └Semantics(container: true; renderObject: RenderSemanticsAnnotations)
I/flutter ( 6559): └_FocusScope(this scope has focus)
I/flutter ( 6559): └Offstage(offstage: false; renderObject: RenderOffstage)
I/flutter ( 6559): └IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer)
I/flutter ( 6559): └_MountainViewPageTransition(animation: AnimationController(⏭ 1.000; paused; for MaterialPageRoute<void>(/))➩ProxyAnimation➩Cubic(0.40, 0.00, 0.20, 1.00)➩Tween<Offset>(Offset(0.0, 1.0) → Offset(0.0, 0.0))➩Offset(0.0, 0.0); state: _AnimatedState(552160732))
I/flutter ( 6559): └SlideTransition(animation: AnimationController(⏭ 1.000; paused; for MaterialPageRoute<void>(/))➩ProxyAnimation➩Cubic(0.40, 0.00, 0.20, 1.00)➩Tween<Offset>(Offset(0.0, 1.0) → Offset(0.0, 0.0))➩Offset(0.0, 0.0); state: _AnimatedState(714726495))
I/flutter ( 6559): └FractionalTranslation(renderObject: RenderFractionalTranslation)
I/flutter ( 6559): └RepaintBoundary(renderObject: RenderRepaintBoundary)
I/flutter ( 6559): └PageStorage([GlobalKey 619728754])
I/flutter ( 6559): └_ModalScopeStatus(active)
I/flutter ( 6559): └AppHome()
I/flutter ( 6559): └Material(MaterialType.canvas; elevation: 0; state: _MaterialState(780114997))
I/flutter ( 6559): └AnimatedContainer(duration: 200ms; has background; state: _AnimatedContainerState(616063822; ticker inactive; has background))
I/flutter ( 6559): └Container(bg: BoxDecoration())
I/flutter ( 6559): └DecoratedBox(renderObject: RenderDecoratedBox)
I/flutter ( 6559): └Container(bg: BoxDecoration(backgroundColor: Color(0xfffafafa)))
I/flutter ( 6559): └DecoratedBox(renderObject: RenderDecoratedBox)
I/flutter ( 6559): └NotificationListener<LayoutChangedNotification>()
I/flutter ( 6559): └_InkFeature([GlobalKey ink renderer]; renderObject: _RenderInkFeatures)
I/flutter ( 6559): └AnimatedDefaultTextStyle(duration: 200ms; inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 400; baseline: alphabetic; state: _AnimatedDefaultTextStyleState(427742350; ticker inactive))
I/flutter ( 6559): └DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 400; baseline: alphabetic)
I/flutter ( 6559): └Center(alignment: Alignment.center; renderObject: RenderPositionedBox)
I/flutter ( 6559): └TextButton()
I/flutter ( 6559): └MaterialButton(state: _MaterialButtonState(398724090))
I/flutter ( 6559): └ConstrainedBox(BoxConstraints(88.0<=w<=Infinity, h=36.0); renderObject: RenderConstrainedBox relayoutBoundary=up1)
I/flutter ( 6559): └AnimatedDefaultTextStyle(duration: 200ms; inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 500; baseline: alphabetic; state: _AnimatedDefaultTextStyleState(315134664; ticker inactive))
I/flutter ( 6559): └DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 500; baseline: alphabetic)
I/flutter ( 6559): └IconTheme(color: Color(0xdd000000))
I/flutter ( 6559): └InkWell(state: _InkResponseState<InkResponse>(369160267))
I/flutter ( 6559): └GestureDetector()
I/flutter ( 6559): └RawGestureDetector(state: RawGestureDetectorState(175370983; gestures: tap; behavior: opaque))
I/flutter ( 6559): └_GestureSemantics(renderObject: RenderSemanticsGestureHandler relayoutBoundary=up2)
I/flutter ( 6559): └Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener relayoutBoundary=up3)
I/flutter ( 6559): └Container(padding: EdgeInsets(16.0, 0.0, 16.0, 0.0))
I/flutter ( 6559): └Padding(renderObject: RenderPadding relayoutBoundary=up4)
I/flutter ( 6559): └Center(alignment: Alignment.center; widthFactor: 1.0; renderObject: RenderPositionedBox relayoutBoundary=up5)
I/flutter ( 6559): └Text("Dump App")
I/flutter ( 6559): └RichText(renderObject: RenderParagraph relayoutBoundary=up6)
これは「平坦化された」ツリーで、投影されたすべてのウィジェットが表示されています。
さまざまなビルド機能を通じて。 (これは、次の場合に得られる木です。
あなたが呼ぶtoStringDeep()
ウィジェット ツリーのルートにあります)。
ウィジェットには表示されないウィジェットがたくさん表示されます。
アプリケーションのソース。フレームワークによって挿入されるため、
ウィジェットのビルド関数。例えば、InkFeature
の実装の詳細です。Material
ウィジェット。
以来、debugDumpApp()
ボタンが変化すると呼び出しが呼び出されます
押されてから解放されるまでの時間は一致します。TextButton
オブジェクト呼び出しsetState()
したがって、それ自体が汚れているとマークされます。だからこそ、ダンプを見ると、
「ダーティ」としてマークされた特定のオブジェクトが表示されるはずです。なんてこともわかります
ジェスチャ リスナーが登録されています。この場合、単一の
GestureDetector がリストされており、「タップ」ジェスチャのみをリッスンしています
(「タップ」は、TapGestureDetector
のtoStringShort
関数)。
独自のウィジェットを作成する場合は、オーバーライドすることで情報を追加できます。debugFillProperties()
。追加診断プロパティオブジェクトをメソッドの引数に追加し、スーパークラスのメソッドを呼び出します。
この機能とは、toString
を埋めるために使用するメソッド
ウィジェットの説明。
レンダーツリー
レイアウトの問題をデバッグしようとしている場合は、ウィジェット レイヤーの
ツリーの詳細が不十分である可能性があります。その場合、ダンプできます
呼び出しによるツリーのレンダリングdebugDumpRenderTree()
。
同様にdebugDumpApp()
、これは多かれ少なかれいつでも呼び出すことができます
ただし、レイアウトまたはペイント段階中は除きます。原則として、
からそれを呼び出すフレームコールバックまたは、イベント ハンドラーが最適な解決策です。
電話をかけるにはdebugDumpRenderTree()
を追加する必要がありますimport
'package:flutter/rendering.dart';
ソースファイルに。
前の小さな例の出力は次のようになります。 以下:
I/flutter ( 6559): RenderView
I/flutter ( 6559): │ debug mode enabled - android
I/flutter ( 6559): │ window size: Size(1080.0, 1794.0) (in physical pixels)
I/flutter ( 6559): │ device pixel ratio: 2.625 (physical pixels per logical pixel)
I/flutter ( 6559): │ configuration: Size(411.4, 683.4) at 2.625x (in logical pixels)
I/flutter ( 6559): │
I/flutter ( 6559): └─child: RenderCustomPaint
I/flutter ( 6559): │ creator: CustomPaint ← Banner ← CheckedModeBanner ←
I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ←
I/flutter ( 6559): │ Theme ← AnimatedTheme ← ScrollConfiguration ← MaterialApp ←
I/flutter ( 6559): │ [root]
I/flutter ( 6559): │ parentData: <none>
I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): │ size: Size(411.4, 683.4)
I/flutter ( 6559): │
I/flutter ( 6559): └─child: RenderPointerListener
I/flutter ( 6559): │ creator: Listener ← Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery
I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ←
I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ←
I/flutter ( 6559): │ Theme ← AnimatedTheme ← ⋯
I/flutter ( 6559): │ parentData: <none>
I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): │ size: Size(411.4, 683.4)
I/flutter ( 6559): │ behavior: defer-to-child
I/flutter ( 6559): │ listeners: down, up, cancel
I/flutter ( 6559): │
I/flutter ( 6559): └─child: RenderAbsorbPointer
I/flutter ( 6559): │ creator: AbsorbPointer ← Listener ←
I/flutter ( 6559): │ Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery
I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ←
I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ←
I/flutter ( 6559): │ Theme ← ⋯
I/flutter ( 6559): │ parentData: <none>
I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): │ size: Size(411.4, 683.4)
I/flutter ( 6559): │ absorbing: false
I/flutter ( 6559): │
I/flutter ( 6559): └─child: RenderSemanticsAnnotations
I/flutter ( 6559): │ creator: Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer
I/flutter ( 6559): │ ← Listener ← Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery
I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ←
I/flutter ( 6559): │ ⋯
I/flutter ( 6559): │ parentData: <none>
I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): │ size: Size(411.4, 683.4)
I/flutter ( 6559): │
I/flutter ( 6559): └─child: _RenderTheatre
I/flutter ( 6559): │ creator: _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope ←
I/flutter ( 6559): │ Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ←
I/flutter ( 6559): │ Listener ← Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery
I/flutter ( 6559): │ ← DefaultTextStyle ← ⋯
I/flutter ( 6559): │ parentData: <none>
I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): │ size: Size(411.4, 683.4)
I/flutter ( 6559): │
I/flutter ( 6559): ├─onstage: RenderStack
I/flutter ( 6559): ╎ │ creator: Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ←
I/flutter ( 6559): ╎ │ _FocusScope ← Semantics ← Focus-[GlobalKey 489139594] ←
I/flutter ( 6559): ╎ │ AbsorbPointer ← Listener ←
I/flutter ( 6559): ╎ │ Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): ╎ │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery
I/flutter ( 6559): ╎ │ ← ⋯
I/flutter ( 6559): ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0)
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ ├─child 1: RenderIgnorePointer
I/flutter ( 6559): ╎ │ │ creator: IgnorePointer ← _OverlayEntry-[GlobalKey 612888877] ←
I/flutter ( 6559): ╎ │ │ Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope
I/flutter ( 6559): ╎ │ │ ← Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ←
I/flutter ( 6559): ╎ │ │ Listener ← Navigator-[GlobalObjectKey<NavigatorState>
I/flutter ( 6559): ╎ │ │ _WidgetsAppState(552902158)] ← Title ← ⋯
I/flutter ( 6559): ╎ │ │ parentData: not positioned; offset=Offset(0.0, 0.0)
I/flutter ( 6559): ╎ │ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ │ ignoring: false
I/flutter ( 6559): ╎ │ │ ignoringSemantics: implicitly false
I/flutter ( 6559): ╎ │ │
I/flutter ( 6559): ╎ │ └─child: RenderSemanticsAnnotations
I/flutter ( 6559): ╎ │ │ creator: Semantics ← ModalBarrier ← IgnorePointer ←
I/flutter ( 6559): ╎ │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ←
I/flutter ( 6559): ╎ │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← Semantics ←
I/flutter ( 6559): ╎ │ │ Focus-[GlobalKey 489139594] ← AbsorbPointer ← Listener ← ⋯
I/flutter ( 6559): ╎ │ │ parentData: <none>
I/flutter ( 6559): ╎ │ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ │
I/flutter ( 6559): ╎ │ └─child: RenderSemanticsGestureHandler
I/flutter ( 6559): ╎ │ │ creator: _GestureSemantics ← RawGestureDetector ← GestureDetector
I/flutter ( 6559): ╎ │ │ ← Semantics ← ModalBarrier ← IgnorePointer ←
I/flutter ( 6559): ╎ │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ←
I/flutter ( 6559): ╎ │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← Semantics ← ⋯
I/flutter ( 6559): ╎ │ │ parentData: <none>
I/flutter ( 6559): ╎ │ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ │
I/flutter ( 6559): ╎ │ └─child: RenderPointerListener
I/flutter ( 6559): ╎ │ │ creator: Listener ← _GestureSemantics ← RawGestureDetector ←
I/flutter ( 6559): ╎ │ │ GestureDetector ← Semantics ← ModalBarrier ← IgnorePointer ←
I/flutter ( 6559): ╎ │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ←
I/flutter ( 6559): ╎ │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← ⋯
I/flutter ( 6559): ╎ │ │ parentData: <none>
I/flutter ( 6559): ╎ │ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ │ behavior: opaque
I/flutter ( 6559): ╎ │ │ listeners: down
I/flutter ( 6559): ╎ │ │
I/flutter ( 6559): ╎ │ └─child: RenderConstrainedBox
I/flutter ( 6559): ╎ │ creator: ConstrainedBox ← Listener ← _GestureSemantics ←
I/flutter ( 6559): ╎ │ RawGestureDetector ← GestureDetector ← Semantics ← ModalBarrier
I/flutter ( 6559): ╎ │ ← IgnorePointer ← _OverlayEntry-[GlobalKey 612888877] ← Stack ←
I/flutter ( 6559): ╎ │ _Theatre ← Overlay-[GlobalKey 199833992] ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ additionalConstraints: BoxConstraints(biggest)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child 2: RenderSemanticsAnnotations
I/flutter ( 6559): ╎ │ creator: Semantics ← Focus-[GlobalObjectKey
I/flutter ( 6559): ╎ │ MaterialPageRoute<void>(875520219)] ← _ModalScope-[GlobalKey
I/flutter ( 6559): ╎ │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ←
I/flutter ( 6559): ╎ │ _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope ←
I/flutter ( 6559): ╎ │ Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ←
I/flutter ( 6559): ╎ │ Listener ← ⋯
I/flutter ( 6559): ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0)
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderOffstage
I/flutter ( 6559): ╎ │ creator: Offstage ← _FocusScope ← Semantics ←
I/flutter ( 6559): ╎ │ Focus-[GlobalObjectKey MaterialPageRoute<void>(875520219)] ←
I/flutter ( 6559): ╎ │ _ModalScope-[GlobalKey 816151164] ← _OverlayEntry-[GlobalKey
I/flutter ( 6559): ╎ │ 727622716] ← Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ←
I/flutter ( 6559): ╎ │ _FocusScope ← Semantics ← Focus-[GlobalKey 489139594] ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ offstage: false
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderIgnorePointer
I/flutter ( 6559): ╎ │ creator: IgnorePointer ← Offstage ← _FocusScope ← Semantics ←
I/flutter ( 6559): ╎ │ Focus-[GlobalObjectKey MaterialPageRoute<void>(875520219)] ←
I/flutter ( 6559): ╎ │ _ModalScope-[GlobalKey 816151164] ← _OverlayEntry-[GlobalKey
I/flutter ( 6559): ╎ │ 727622716] ← Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ←
I/flutter ( 6559): ╎ │ _FocusScope ← Semantics ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ ignoring: false
I/flutter ( 6559): ╎ │ ignoringSemantics: implicitly false
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderFractionalTranslation
I/flutter ( 6559): ╎ │ creator: FractionalTranslation ← SlideTransition ←
I/flutter ( 6559): ╎ │ _MountainViewPageTransition ← IgnorePointer ← Offstage ←
I/flutter ( 6559): ╎ │ _FocusScope ← Semantics ← Focus-[GlobalObjectKey
I/flutter ( 6559): ╎ │ MaterialPageRoute<void>(875520219)] ← _ModalScope-[GlobalKey
I/flutter ( 6559): ╎ │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ←
I/flutter ( 6559): ╎ │ _Theatre ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ translation: Offset(0.0, 0.0)
I/flutter ( 6559): ╎ │ transformHitTests: true
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderRepaintBoundary
I/flutter ( 6559): ╎ │ creator: RepaintBoundary ← FractionalTranslation ←
I/flutter ( 6559): ╎ │ SlideTransition ← _MountainViewPageTransition ← IgnorePointer ←
I/flutter ( 6559): ╎ │ Offstage ← _FocusScope ← Semantics ← Focus-[GlobalObjectKey
I/flutter ( 6559): ╎ │ MaterialPageRoute<void>(875520219)] ← _ModalScope-[GlobalKey
I/flutter ( 6559): ╎ │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ metrics: 83.3% useful (1 bad vs 5 good)
I/flutter ( 6559): ╎ │ diagnosis: this is a useful repaint boundary and should be kept
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderDecoratedBox
I/flutter ( 6559): ╎ │ creator: DecoratedBox ← Container ← AnimatedContainer ← Material
I/flutter ( 6559): ╎ │ ← AppHome ← _ModalScopeStatus ← PageStorage-[GlobalKey
I/flutter ( 6559): ╎ │ 619728754] ← RepaintBoundary ← FractionalTranslation ←
I/flutter ( 6559): ╎ │ SlideTransition ← _MountainViewPageTransition ← IgnorePointer ←
I/flutter ( 6559): ╎ │ ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ decoration:
I/flutter ( 6559): ╎ │ <no decorations specified>
I/flutter ( 6559): ╎ │ configuration: ImageConfiguration(bundle:
I/flutter ( 6559): ╎ │ PlatformAssetBundle@367106502(), devicePixelRatio: 2.625,
I/flutter ( 6559): ╎ │ platform: android)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderDecoratedBox
I/flutter ( 6559): ╎ │ creator: DecoratedBox ← Container ← DecoratedBox ← Container ←
I/flutter ( 6559): ╎ │ AnimatedContainer ← Material ← AppHome ← _ModalScopeStatus ←
I/flutter ( 6559): ╎ │ PageStorage-[GlobalKey 619728754] ← RepaintBoundary ←
I/flutter ( 6559): ╎ │ FractionalTranslation ← SlideTransition ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ decoration:
I/flutter ( 6559): ╎ │ backgroundColor: Color(0xfffafafa)
I/flutter ( 6559): ╎ │ configuration: ImageConfiguration(bundle:
I/flutter ( 6559): ╎ │ PlatformAssetBundle@367106502(), devicePixelRatio: 2.625,
I/flutter ( 6559): ╎ │ platform: android)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: _RenderInkFeatures
I/flutter ( 6559): ╎ │ creator: _InkFeature-[GlobalKey ink renderer] ←
I/flutter ( 6559): ╎ │ NotificationListener<LayoutChangedNotification> ← DecoratedBox
I/flutter ( 6559): ╎ │ ← Container ← DecoratedBox ← Container ← AnimatedContainer ←
I/flutter ( 6559): ╎ │ Material ← AppHome ← _ModalScopeStatus ← PageStorage-[GlobalKey
I/flutter ( 6559): ╎ │ 619728754] ← RepaintBoundary ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderPositionedBox
I/flutter ( 6559): ╎ │ creator: Center ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
I/flutter ( 6559): ╎ │ _InkFeature-[GlobalKey ink renderer] ←
I/flutter ( 6559): ╎ │ NotificationListener<LayoutChangedNotification> ← DecoratedBox
I/flutter ( 6559): ╎ │ ← Container ← DecoratedBox ← Container ← AnimatedContainer ←
I/flutter ( 6559): ╎ │ Material ← AppHome ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter ( 6559): ╎ │ size: Size(411.4, 683.4)
I/flutter ( 6559): ╎ │ alignment: Alignment.center
I/flutter ( 6559): ╎ │ widthFactor: expand
I/flutter ( 6559): ╎ │ heightFactor: expand
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderConstrainedBox relayoutBoundary=up1
I/flutter ( 6559): ╎ │ creator: ConstrainedBox ← MaterialButton ← TextButton ← Center ←
I/flutter ( 6559): ╎ │ DefaultTextStyle ← AnimatedDefaultTextStyle ←
I/flutter ( 6559): ╎ │ _InkFeature-[GlobalKey ink renderer] ←
I/flutter ( 6559): ╎ │ NotificationListener<LayoutChangedNotification> ← DecoratedBox
I/flutter ( 6559): ╎ │ ← Container ← DecoratedBox ← Container ← ⋯
I/flutter ( 6559): ╎ │ parentData: offset=Offset(156.7, 323.7)
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=683.4)
I/flutter ( 6559): ╎ │ size: Size(98.0, 36.0)
I/flutter ( 6559): ╎ │ additionalConstraints: BoxConstraints(88.0<=w<=Infinity, h=36.0)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderSemanticsGestureHandler relayoutBoundary=up2
I/flutter ( 6559): ╎ │ creator: _GestureSemantics ← RawGestureDetector ← GestureDetector
I/flutter ( 6559): ╎ │ ← InkWell ← IconTheme ← DefaultTextStyle ←
I/flutter ( 6559): ╎ │ AnimatedDefaultTextStyle ← ConstrainedBox ← MaterialButton ←
I/flutter ( 6559): ╎ │ TextButton ← Center ← DefaultTextStyle ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
I/flutter ( 6559): ╎ │ size: Size(98.0, 36.0)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderPointerListener relayoutBoundary=up3
I/flutter ( 6559): ╎ │ creator: Listener ← _GestureSemantics ← RawGestureDetector ←
I/flutter ( 6559): ╎ │ GestureDetector ← InkWell ← IconTheme ← DefaultTextStyle ←
I/flutter ( 6559): ╎ │ AnimatedDefaultTextStyle ← ConstrainedBox ← MaterialButton ←
I/flutter ( 6559): ╎ │ TextButton ← Center ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
I/flutter ( 6559): ╎ │ size: Size(98.0, 36.0)
I/flutter ( 6559): ╎ │ behavior: opaque
I/flutter ( 6559): ╎ │ listeners: down
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderPadding relayoutBoundary=up4
I/flutter ( 6559): ╎ │ creator: Padding ← Container ← Listener ← _GestureSemantics ←
I/flutter ( 6559): ╎ │ RawGestureDetector ← GestureDetector ← InkWell ← IconTheme ←
I/flutter ( 6559): ╎ │ DefaultTextStyle ← AnimatedDefaultTextStyle ← ConstrainedBox ←
I/flutter ( 6559): ╎ │ MaterialButton ← ⋯
I/flutter ( 6559): ╎ │ parentData: <none>
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
I/flutter ( 6559): ╎ │ size: Size(98.0, 36.0)
I/flutter ( 6559): ╎ │ padding: EdgeInsets(16.0, 0.0, 16.0, 0.0)
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderPositionedBox relayoutBoundary=up5
I/flutter ( 6559): ╎ │ creator: Center ← Padding ← Container ← Listener ←
I/flutter ( 6559): ╎ │ _GestureSemantics ← RawGestureDetector ← GestureDetector ←
I/flutter ( 6559): ╎ │ InkWell ← IconTheme ← DefaultTextStyle ←
I/flutter ( 6559): ╎ │ AnimatedDefaultTextStyle ← ConstrainedBox ← ⋯
I/flutter ( 6559): ╎ │ parentData: offset=Offset(16.0, 0.0)
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(56.0<=w<=379.4, h=36.0)
I/flutter ( 6559): ╎ │ size: Size(66.0, 36.0)
I/flutter ( 6559): ╎ │ alignment: Alignment.center
I/flutter ( 6559): ╎ │ widthFactor: 1.0
I/flutter ( 6559): ╎ │ heightFactor: expand
I/flutter ( 6559): ╎ │
I/flutter ( 6559): ╎ └─child: RenderParagraph relayoutBoundary=up6
I/flutter ( 6559): ╎ │ creator: RichText ← Text ← Center ← Padding ← Container ←
I/flutter ( 6559): ╎ │ Listener ← _GestureSemantics ← RawGestureDetector ←
I/flutter ( 6559): ╎ │ GestureDetector ← InkWell ← IconTheme ← DefaultTextStyle ← ⋯
I/flutter ( 6559): ╎ │ parentData: offset=Offset(0.0, 10.0)
I/flutter ( 6559): ╎ │ constraints: BoxConstraints(0.0<=w<=379.4, 0.0<=h<=36.0)
I/flutter ( 6559): ╎ │ size: Size(66.0, 16.0)
I/flutter ( 6559): ╎ ╘═╦══ text ═══
I/flutter ( 6559): ╎ ║ TextSpan:
I/flutter ( 6559): ╎ ║ inherit: false
I/flutter ( 6559): ╎ ║ color: Color(0xdd000000)
I/flutter ( 6559): ╎ ║ family: "Roboto"
I/flutter ( 6559): ╎ ║ size: 14.0
I/flutter ( 6559): ╎ ║ weight: 500
I/flutter ( 6559): ╎ ║ baseline: alphabetic
I/flutter ( 6559): ╎ ║ "Dump App"
I/flutter ( 6559): ╎ ╚═══════════
I/flutter ( 6559): ╎
I/flutter ( 6559): └╌no offstage children
これはルートの出力ですRenderObject
オブジェクトのtoStringDeep()
関数。
レイアウトの問題をデバッグする場合、注目すべき重要なフィールドは次のとおりです。size
とconstraints
田畑。制約はツリーの下に流れていきます。
そしてサイズは元に戻ります。
たとえば、前のダンプでは、ウィンドウ サイズがSize(411.4, 683.4)
、すべてのボックスを強制的に下に置くために使用されます。RenderPositionedBox
画面のサイズになります。
の制約BoxConstraints(w=411.4, h=683.4)
。
のRenderPositionedBox
、ダンプには、によって作成されたことが示されています。Center
ウィジェット (で説明されているように)creator
分野)、
子の制約をこれの緩いバージョンに設定します。BoxConstraints(0.0<=w<=411.4, 0.0<=h<=683.4)
。その子、RenderPadding
、さらにこれらの制約を挿入して、
パディングのためのスペースがあるため、RenderConstrainedBox
という緩い制約があるBoxConstraints(0.0<=w<=395.4,
0.0<=h<=667.4)
。このオブジェクトは、creator
フィールドが教えてくれたのは、
おそらくその一部TextButton
の定義、
コンテンツの最小幅を 88 ピクセルに設定し、
比高36.0。 (これはTextButton
クラス実装
ボタンの寸法に関するマテリアル デザイン ガイドライン。)
一番奥のRenderPositionedBox
再び制約を緩めると、
今度はテキストをボタン内の中央に配置します。のRenderParagraph
内容に基づいてサイズが選択されます。
ここで、チェーンを遡ってサイズを追跡すると、
テキストのサイズがどのように影響するかがわかります。
ボタンを形成するすべてのボックスの幅。
お子様の寸法を自分自身のサイズに合わせて調整します。
これを確認するもう 1 つの方法は、「relayoutSubtreeRoot」を確認することです。
各ボックスの説明の一部。基本的にその方法を示しています。
多くの先祖は、何らかの形でこの要素のサイズに依存しています。
したがって、RenderParagraph
がありますrelayoutSubtreeRoot=up8
、
つまり、RenderParagraph
汚れている、
8人の祖先も汚れていなければなりません。
新しい次元の影響を受けます。
独自のレンダー オブジェクトを作成する場合は、
オーバーライドによるダンプdebugFillProperties()
。
追加診断プロパティオブジェクトをメソッドの引数に追加し、スーパークラスのメソッドを呼び出します。
レイヤーツリー
合成の問題をデバッグしようとしている場合は、次を使用できます。debugDumpLayerTree()
。
前の例の場合、次のように出力されます。
I/flutter : TransformLayer
I/flutter : │ creator: [root]
I/flutter : │ offset: Offset(0.0, 0.0)
I/flutter : │ transform:
I/flutter : │ [0] 3.5,0.0,0.0,0.0
I/flutter : │ [1] 0.0,3.5,0.0,0.0
I/flutter : │ [2] 0.0,0.0,1.0,0.0
I/flutter : │ [3] 0.0,0.0,0.0,1.0
I/flutter : │
I/flutter : ├─child 1: OffsetLayer
I/flutter : │ │ creator: RepaintBoundary ← _FocusScope ← Semantics ← Focus-[GlobalObjectKey MaterialPageRoute(560156430)] ← _ModalScope-[GlobalKey 328026813] ← _OverlayEntry-[GlobalKey 388965355] ← Stack ← Overlay-[GlobalKey 625702218] ← Navigator-[GlobalObjectKey _MaterialAppState(859106034)] ← Title ← ⋯
I/flutter : │ │ offset: Offset(0.0, 0.0)
I/flutter : │ │
I/flutter : │ └─child 1: PictureLayer
I/flutter : │
I/flutter : └─child 2: PictureLayer
これは呼び出しの出力ですtoStringDeep
根元にLayer
物体。
ルートの変換はデバイスを適用する変換です ピクセル比。この場合、各デバイス ピクセルの比率は 3.5 になります。 論理ピクセル。
のRepaintBoundary
ウィジェット、RenderRepaintBoundary
レンダー ツリーで、レイヤー ツリーに新しいレイヤーを作成します。これは
再塗装の必要量を減らすために使用されます。
フォーカスツリー
フォーカスまたはショートカットの問題をデバッグするには、フォーカス ツリーをダンプします。
使用してdebugDumpFocusTree()
。
例えば:
I/flutter : FocusManager#6fb59
I/flutter : │ primaryFocus: FocusScopeNode#3c26f(_ModalScopeState<dynamic>
I/flutter : │ Focus Scope [PRIMARY FOCUS])
I/flutter : │ primaryFocusCreator: FocusScope ← PrimaryScrollController ←
I/flutter : │ _ActionsScope ← Actions ← Builder ← PageStorage ← Offstage ←
I/flutter : │ _ModalScopeStatus ← UnmanagedRestorationScope ←
I/flutter : │ RestorationScope ← AnimatedBuilder ←
I/flutter : │ _ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#f36a2]
I/flutter : │ ← Semantics ← _RenderTheaterMarker ← _EffectiveTickerMode ←
I/flutter : │ TickerMode ←
I/flutter : │ _OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#2e2a3]
I/flutter : │ ← _Theater ← Overlay-[LabeledGlobalKey<OverlayState>#89fc1] ←
I/flutter : │ UnmanagedRestorationScope ← ⋯
I/flutter : │
I/flutter : └─rootScope: FocusScopeNode#95ff1(Root Focus Scope [IN FOCUS PATH])
I/flutter : │ IN FOCUS PATH
I/flutter : │ focusedChildren: FocusScopeNode#001cc(Navigator Scope [IN FOCUS
I/flutter : │ PATH])
I/flutter : │
I/flutter : └─Child 1: FocusNode#79786([IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusNode#15aec(Shortcuts [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusNode#3514b(Shortcuts [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: _FocusTraversalGroupNode#0ccda(FocusTraversalGroup [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusNode#e2413(Shortcuts [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusScopeNode#001cc(Navigator Scope [IN FOCUS PATH])
I/flutter : │ context: FocusScope
I/flutter : │ IN FOCUS PATH
I/flutter : │ focusedChildren: FocusScopeNode#3c26f(_ModalScopeState<dynamic>
I/flutter : │ Focus Scope [PRIMARY FOCUS])
I/flutter : │
I/flutter : └─Child 1: _FocusTraversalGroupNode#1d456(FocusTraversalGroup [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ NOT FOCUSABLE
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusNode#3635f(Navigator [IN FOCUS PATH])
I/flutter : │ context: Focus
I/flutter : │ IN FOCUS PATH
I/flutter : │
I/flutter : └─Child 1: FocusScopeNode#3c26f(_ModalScopeState<dynamic> Focus Scope [PRIMARY FOCUS])
I/flutter : context: FocusScope
I/flutter : PRIMARY FOCUS
フォーカスされたノードにはラベルが付けられますPRIMARY FOCUS
。フォーカス ノードの祖先は次のとおりです。
ラベルが貼られたIN FOCUS PATH
。
アプリがFocus
ウィジェットを使用できます。debugLabel
プロパティを使用して、ツリー内でフォーカス ノードを見つけやすくします。
を使用することもできます。debugFocusChanges
有効にするブール値のフラグ
フォーカスが変更されたときの広範なログ記録。
セマンティクスツリー
セマンティクス ツリーのダンプを取得することもできます。
(システム アクセシビリティ API に提示されるツリー) を使用してdebugDumpSemanticsTree()
。これを使用するには、
たとえば、最初にアクセシビリティを有効にする必要があります。
システム アクセシビリティ ツールを有効にするか、SemanticsDebugger
。
前の例の場合、次のように出力されます。
I/flutter : SemanticsNode(0; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter : ├SemanticsNode(1; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter : │ └SemanticsNode(2; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4); canBeTapped)
I/flutter : └SemanticsNode(3; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
I/flutter : └SemanticsNode(4; Rect.fromLTRB(0.0, 0.0, 82.0, 36.0); canBeTapped; "Dump App")
スケジュール設定
フレームに対してイベントが発生する場所を確認するには
開始/終了を切り替えることができます。debugPrintBeginFrameBanner
そしてそのdebugPrintEndFrameBanner
を出力するブール値
フレームの最初と最後をコンソールに送信します。
例えば:
I/flutter : ▄▄▄▄▄▄▄▄ Frame 12 30s 437.086ms ▄▄▄▄▄▄▄▄
I/flutter : Debug print: Am I performing this work more than once per frame?
I/flutter : Debug print: Am I performing this work more than once per frame?
I/flutter : ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
のdebugPrintScheduleFrameStacks
フラグも使用できます
現在のフレームをスケジュールする呼び出しスタックを出力します。
デバッグフラグ: レイアウト
設定することで、レイアウトの問題を視覚的にデバッグすることもできます。debugPaintSizeEnabled
にtrue
。
これはからのブール値ですrendering
図書館。かもね
いつでも有効になり、true の間はすべてのペイントに影響します。
設定する最も簡単な方法は、void main()
エントリーポイント。次のコードの例を参照してください。
//add import to rendering library
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(const MyApp());
}
有効にすると、すべてのボックスに明るい青緑の境界線が表示されます。
パディング(次のようなウィジェットから)Padding
) は色褪せて表示されます
青、子の周りに濃い青のボックス、位置合わせ
(次のようなウィジェットからCenter
とAlign
) で表示されます
黄色の矢印とスペーサー (次のようなウィジェットから)Container
子供がいない場合)は灰色で表示されます。
のdebugPaintBaselinesEnabled
国旗
同様のことを行いますが、ベースラインを持つオブジェクトに対して行われます。
アルファベットのベースラインは明るい緑色で表示され、
オレンジ色の表意文字ベースライン。
のdebugPaintPointersEnabled
フラグがオンになる
タップされているオブジェクトをすべて削除する特別なモード
ティール色で強調表示されます。これは判断に役立ちます
オブジェクトが何らかの理由で正しくヒットしていないかどうか
テスト (これは、たとえば、実際にテストされた場合に発生する可能性があります)
親の境界外にあるため、
そもそもヒット テストの対象として検討されています)。
たとえば、コンポジター レイヤーをデバッグしようとしている場合、
追加するかどうか、そしてどこに追加するかを決定するRepaintBoundary
ウィジェットを使用できます。debugPaintLayerBordersEnabled
各レイヤーの境界をオレンジ色で囲むフラグ、
またはdebugRepaintRainbowEnabled
国旗、
これにより、レイヤーが回転するセットでオーバーレイされます。
再塗装されるたびに色が変わります。
これらのフラグはすべて、次の環境でのみ機能します。デバッグモード。
一般に、Flutter フレームワーク内の次のものはすべて、
「debug...
」はデバッグモードでのみ動作します。
アニメーションのデバッグ
をセットするtimeDilation
変数 (からscheduler
library) を 1.0 より大きい数値 (たとえば、50.0) に設定します。
これはアプリの起動時に一度だけ設定することをお勧めします。もし、あんたが
特に、途中で減らす場合は、その場で変更します。
アニメーションが実行されている場合、フレームワークが
時間が逆行することを観察することになるでしょう。
結果としてアサートが発生し、通常は作業が妨げられます。
デバッグフラグ:パフォーマンス
Flutter はさまざまなデバッグ フラグと関数を提供します のさまざまな時点でアプリをデバッグするのに役立ちます。 開発サイクル。これらの機能を使用するには、コンパイルする必要があります デバッグモードで。次のリストは完全ではありませんが、 のいくつかのフラグ (および 1 つの関数) を強調表示します。レンダリングライブラリパフォーマンスの問題をデバッグするため。
これらのフラグは、フレームワーク コードを編集することによって設定できます。
または、モジュールをインポートして値を設定します。main()
方法の後にホットリスタートが続きます。
debugDumpRenderTree()
-
レイアウトまたは再描画中でないときにこの関数を呼び出します。 レンダリング ツリーをコンソールにダンプするフェーズ。 (押すtから
flutter run
このコマンドを呼び出します。) 「RepaintBoundary」を検索して診断を表示します 境界線がどれほど役立つかについて。 debugPaintLayerBordersEnabled
-
保留中
debugRepaintRainbowEnabled
-
Flutter でこのフラグを有効にすることができます。 インスペクターを選択して、ハイライトの再ペイントボタン。 静的ウィジェットが虹の色で回転している場合 (静的ヘッダーなど)、これらの領域は追加の候補です。 境界線を再描画します。
debugPrintMarkNeedsLayoutStacks
-
さらに多くのレイアウトを表示する場合は、このフラグを有効にします 予想よりも (たとえば、タイムライン上、プロフィール上、 またはから
print
レイアウトメソッド内のステートメント)。 有効にすると、コンソールにスタック トレースが表示されます。 各レンダー オブジェクトがダーティとしてマークされる理由を示す レイアウト。使用できますdebugPrintStack()
からのメソッドservices
独自のスタック トレースをオンデマンドで出力するライブラリ、 この種のアプローチがあなたにとって役立つのであれば。 debugPrintMarkNeedsPaintStacks
-
に似ている
debugPrintMarkNeedsLayoutStacks
、 ただし余分な塗装のため。使用できますdebugPrintStack()
からのメソッドservices
独自のスタックを印刷するライブラリ この種のアプローチが役立つ場合は、オンデマンドでトレースします。カスタム パフォーマンス トレースをプログラムで実行するには、 Dart コードの任意のセグメントの壁/CPU 時間を測定します。 Android で行うことと同様ですシステムレース、 使用
dart:developer
タイムラインをラップするユーティリティ 次のような測定したいコード:import 'dart:developer'; void main() { Timeline.startSync('interesting function'); // iWonderHowLongThisTakes(); Timeline.finishSync(); }
次に、DevTools を開きますタイムラインイベントチャートアプリに接続している間、 を確認してくださいダーツ録音オプションがチェックされているパフォーマンス設定、 測定したい機能を実行します。
必ずアプリを実行してくださいプロファイルモード確実に 実行時のパフォーマンス特性は、使用しているパフォーマンス特性とほぼ一致します。 最終製品。
PerformanceOverlay ウィジェットをプログラムで有効にするには、次のようにします。 を設定する
showPerformanceOverlay
財産をtrue
でMaterialApp
、CupertinoApp
、 またWidgetsApp
コンストラクタ:import 'package:flutter/material.dart'; class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( showPerformanceOverlay: true, title: 'My Awesome App', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'My Awesome App'), ); } }
(使用していない場合は、
MaterialApp
、CupertinoApp
、 またWidgetsApp
をラップしても同じ効果が得られます。 アプリケーションをスタックに追加し、ウィジェットをスタックに配置します。 電話して作成したPerformanceOverlay.allEnabled()
。)オーバーレイ内のグラフを解釈する方法については、 見るパフォーマンスオーバーレイのFlutter パフォーマンスのプロファイリング。
プログラムでオーバーレイすることができますマテリアル デザイン ベースライン グリッドアプリの上に を使用して位置合わせを確認するのに役立ちます。
debugShowMaterialGrid
の引数MaterialApp
コンストラクタ。マテリアル以外のアプリケーションでも、同様のことを実現できます。 を使用することによる効果
GridPaper
ウィジェットを直接。